# -*- coding: utf-8 -*-

from PyQt5 import QtCore, QtWidgets
from PyQt5.QtGui import QIcon  # 导入设置图标模块
import base64
import os
import shutil
from copy import copy
from datetime import datetime
from io import BytesIO
from tkinter import filedialog  # tkinter选择文件
# IMG_PATH = askdirectory()
from tkinter import messagebox
# img_path = filedialog.askopenfilename()
from tkinter.filedialog import askdirectory  # tkinter选择文件夹

import cv2
import fitz
import numpy as np
from PIL import Image
from PIL import ImageEnhance
from PyPDF2 import PdfFileWriter
from PyPDF2 import PdfReader, PdfWriter, PdfFileMerger, PdfFileReader
from paddleocr import PPStructure
from paddleocr import PaddleOCR,draw_ocr
from pdf2docx import Converter
from ttkbootstrap import Style
from docx2pdf import convert
import pptx
from pptx.util import Inches

from icon import img  # 引用 icon.py 的图片
from recovery_to_doc import sorted_layout_boxes, convert_info_docx


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(550, 400)  # 设置窗口默认大小
        MainWindow.setWindowIcon(QIcon('picture.ico'))  # 设置软件图标
        MainWindow.setWindowOpacity(0.98)  # 设置窗口透明度
        MainWindow.setStyleSheet('background-color:#ffffff')  # 设置窗口背景颜色，也可以替换为图片
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        #按钮1
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(40, 30, 121, 41))
        self.pushButton.setObjectName("pushButton")
        self.pushButton.setStyleSheet(
            "QPushButton{font-family:'微软雅黑';font-size:12px;color:rgb(255,255,255);border-radius:4px;border:1px solid rgb(144,238,144);}\QPushButton{background-color:rgb(255,255,255);color:rgb(144,238,144)}\QPushButton:hover{background-color:rgb(144,238,144);color:rgb(240,255,255)}")
        self.pushButton.clicked.connect(lambda: self.conver('PdfToImg'))
        # 按钮2
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(210, 30, 121, 41))
        self.pushButton_2.setObjectName("pushButton_2")
        self.pushButton_2.setStyleSheet(
            "QPushButton{font-family:'微软雅黑';font-size:12px;color:rgb(255,255,255);border-radius:4px;border:1px solid rgb(144,238,144);}\QPushButton{background-color:rgb(255,255,255);color:rgb(144,238,144)}\QPushButton:hover{background-color:rgb(144,238,144);color:rgb(240,255,255)}")
        self.pushButton_2.clicked.connect(lambda: self.conver('WordToPdf'))
        # 按钮3
        self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_3.setGeometry(QtCore.QRect(380, 30, 121, 41))
        self.pushButton_3.setObjectName("pushButton_3")
        self.pushButton_3.setStyleSheet(
            "QPushButton{font-family:'微软雅黑';font-size:12px;color:rgb(255,255,255);border-radius:4px;border:1px solid rgb(144,238,144);}\QPushButton{background-color:rgb(255,255,255);color:rgb(144,238,144)}\QPushButton:hover{background-color:rgb(144,238,144);color:rgb(240,255,255)}")
        self.pushButton_3.clicked.connect(lambda: self.conver('PdfToWord'))
        # 按钮4
        self.pushButton_4 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_4.setGeometry(QtCore.QRect(40, 110, 121, 41))
        self.pushButton_4.setObjectName("pushButton_4")
        self.pushButton_4.setStyleSheet(
            "QPushButton{font-family:'微软雅黑';font-size:12px;color:rgb(255,255,255);border-radius:4px;border:1px solid rgb(144,238,144);}\QPushButton{background-color:rgb(255,255,255);color:rgb(144,238,144)}\QPushButton:hover{background-color:rgb(144,238,144);color:rgb(240,255,255)}")
        self.pushButton_4.clicked.connect(lambda: self.conver('PdfToLow'))
        # 按钮5
        self.pushButton_5 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_5.setGeometry(QtCore.QRect(210, 110, 121, 41))
        self.pushButton_5.setObjectName("pushButton_5")
        self.pushButton_5.setStyleSheet(
            "QPushButton{font-family:'微软雅黑';font-size:12px;color:rgb(255,255,255);border-radius:4px;border:1px solid rgb(144,238,144);}\QPushButton{background-color:rgb(255,255,255);color:rgb(144,238,144)}\QPushButton:hover{background-color:rgb(144,238,144);color:rgb(240,255,255)}")
        self.pushButton_5.clicked.connect(lambda: self.conver('PdfToMore'))
        # 按钮6
        self.pushButton_6 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_6.setGeometry(QtCore.QRect(380, 110, 121, 41))
        self.pushButton_6.setObjectName("pushButton_6")
        self.pushButton_6.setStyleSheet(
            "QPushButton{font-family:'微软雅黑';font-size:12px;color:rgb(255,255,255);border-radius:4px;border:1px solid rgb(144,238,144);}\QPushButton{background-color:rgb(255,255,255);color:rgb(144,238,144)}\QPushButton:hover{background-color:rgb(144,238,144);color:rgb(240,255,255)}")
        self.pushButton_6.clicked.connect(lambda: self.conver('PhotoToImg'))
        # 按钮7
        self.pushButton_7 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_7.setGeometry(QtCore.QRect(40, 190, 121, 41))
        self.pushButton_7.setObjectName("pushButton_7")
        self.pushButton_7.setStyleSheet(
            "QPushButton{font-family:'微软雅黑';font-size:12px;color:rgb(255,255,255);border-radius:4px;border:1px solid rgb(144,238,144);}\QPushButton{background-color:rgb(255,255,255);color:rgb(144,238,144)}\QPushButton:hover{background-color:rgb(144,238,144);color:rgb(240,255,255)}")
        self.pushButton.clicked.connect(lambda: self.conver('PhotoToWord'))
        # 按钮8
        self.pushButton_8 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_8.setGeometry(QtCore.QRect(210, 190, 121, 41))
        self.pushButton_8.setObjectName("pushButton_8")
        self.pushButton_8.setStyleSheet(
            "QPushButton{font-family:'微软雅黑';font-size:12px;color:rgb(255,255,255);border-radius:4px;border:1px solid rgb(144,238,144);}\QPushButton{background-color:rgb(255,255,255);color:rgb(144,238,144)}\QPushButton:hover{background-color:rgb(144,238,144);color:rgb(240,255,255)}")
        self.pushButton_8.clicked.connect(lambda: self.conver('PdfToRWord'))
        # 按钮9
        self.pushButton_9 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_9.setGeometry(QtCore.QRect(380, 190, 121, 41))
        self.pushButton_9.setObjectName("pushButton_9")
        self.pushButton_9.setStyleSheet(
            "QPushButton{font-family:'微软雅黑';font-size:12px;color:rgb(255,255,255);border-radius:4px;border:1px solid rgb(144,238,144);}\QPushButton{background-color:rgb(255,255,255);color:rgb(144,238,144)}\QPushButton:hover{background-color:rgb(144,238,144);color:rgb(240,255,255)}")
        self.pushButton_9.clicked.connect(lambda: self.coverpath('PdfToOne'))
        # 按钮10
        self.pushButton_10 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_10.setGeometry(QtCore.QRect(40, 270, 121, 41))
        self.pushButton_10.setObjectName("pushButton_10")
        self.pushButton_10.setStyleSheet(
            "QPushButton{font-family:'微软雅黑';font-size:12px;color:rgb(255,255,255);border-radius:4px;border:1px solid rgb(144,238,144);}\QPushButton{background-color:rgb(255,255,255);color:rgb(144,238,144)}\QPushButton:hover{background-color:rgb(144,238,144);color:rgb(240,255,255)}")
        self.pushButton_10.clicked.connect(lambda: self.conver('ImageToLow'))
        # 按钮11
        self.pushButton_11 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_11.setGeometry(QtCore.QRect(210, 270, 121, 41))
        self.pushButton_11.setObjectName("pushButton_11")
        self.pushButton_11.setStyleSheet(
            "QPushButton{font-family:'微软雅黑';font-size:12px;color:rgb(255,255,255);border-radius:4px;border:1px solid rgb(144,238,144);}\QPushButton{background-color:rgb(255,255,255);color:rgb(144,238,144)}\QPushButton:hover{background-color:rgb(144,238,144);color:rgb(240,255,255)}")
        self.pushButton_11.clicked.connect(lambda: self.conver('PdfToMark'))
        # 按钮12
        self.pushButton_12 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_12.setGeometry(QtCore.QRect(380, 270, 121, 41))
        self.pushButton_12.setObjectName("pushButton_12")
        self.pushButton_12.setStyleSheet(
            "QPushButton{font-family:'微软雅黑';font-size:12px;color:rgb(255,255,255);border-radius:4px;border:1px solid rgb(144,238,144);}\QPushButton{background-color:rgb(255,255,255);color:rgb(144,238,144)}\QPushButton:hover{background-color:rgb(144,238,144);color:rgb(240,255,255)}")
        self.pushButton_12.clicked.connect(lambda: self.conver('PdfToPpt'))

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    # 设置选择文件
    def conver(self, type):
        selectFile = filedialog.askopenfilename()
        obj = Change(selectFile)
        res = getattr(obj, type)
        self.message(res())

    def message(self, text):
        messagebox.showinfo('结果', text)

    def coverpath(self, type):
        selectPATH = askdirectory()
        obj = Changefile(selectPATH)
        res = getattr(obj, type)
        self.message(res())

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "PDF工具合集V2.9(黄朝勋)"))
        self.pushButton.setText(_translate("MainWindow", "PDF转图片功能"))
        self.pushButton_2.setText(_translate("MainWindow", "word转PDF功能"))
        self.pushButton_3.setText(_translate("MainWindow", "PDF转word功能"))
        self.pushButton_4.setText(_translate("MainWindow", "PDF文件压缩功能"))
        self.pushButton_5.setText(_translate("MainWindow", "PDF文件拆分功能"))
        self.pushButton_6.setText(_translate("MainWindow", "照片磨皮修复功能"))
        self.pushButton_7.setText(_translate("MainWindow", "图片文字提取功能"))
        self.pushButton_8.setText(_translate("MainWindow", "PDF文字提取功能"))
        self.pushButton_9.setText(_translate("MainWindow", "PDF文件合并功能"))
        self.pushButton_10.setText(_translate("MainWindow", "图片高级压缩功能"))
        self.pushButton_11.setText(_translate("MainWindow", "PDF添加水印功能"))
        self.pushButton_12.setText(_translate("MainWindow", "PDF转PPT功能"))


# 读取base64转码后的数据，并设置压缩图标
picture = open("picture.ico", "wb+")
picture.write(base64.b64decode(img))
picture.close()

style = Style(theme='minty')


# 定义打开的文件
class Change:
    def __init__(self, filename):
        self.filename = filename

    # 1、pdf转图片模块
    def PdfToImg(self):
        try:
            self.pdf = fitz.open(self.filename)
            self.pageCount = self.pdf.pageCount
            for pg in range(self.pageCount):
                page = self.pdf[pg]
                trans = fitz.Matrix(2.0, 2.0).prerotate(0)
                pm = page.get_pixmap(matrix=trans, alpha=False)
                pm.save(self.filename + '%s.png' % pg)
            return '转换图片完成'
        except Exception as e:
            return e

    # 2、word转pdf模块
    def WordToPdf(self):
        # doc 文件 需要先转为 docx 文件（一般情况下、直接修改后缀名、不会对原文件有影响）
        inputFile = self.filename  # 要转换的文件：已存在
        outputFile = self.filename + '.pdf'  # 要生成的文件：不存在
        # 转换PDF中写入内容
        convert(inputFile, outputFile)
        return '转换DPF完成'

    # 3、PDF转word模块
    def PdfToWord(self):
        Wordname = (self.filename + '.docx')
        cv = Converter(self.filename)
        cv.convert(Wordname, start=0, end=None)
        cv.close()
        return '转换word完成'

    # 4、PDF文件压缩模块
    def PdfToLow(self):
        reader = PdfReader(self.filename)
        writer = PdfWriter()
        for page in reader.pages:
            page.compress_content_streams()
            writer.add_page(page)
        with open(self.filename + '.pdf', 'wb') as f:
            writer.write(f)
        return 'PDF文件压缩完成'

    # 5、PDF拆分模块
    def PdfToMore(self):
        reader = PdfReader(self.filename)
        writer = self.filename
        for i in range(0, reader.getNumPages()):
            pdf_writer = PdfWriter()
            pdf_writer.addPage(reader.getPage(i))
            with open(writer + '-{}.pdf'.format(str(i)), 'wb') as fh:
                pdf_writer.write(fh)
        return '将PDF文件中的每页生成单独一个PDF文件完成'

    # 6、照片磨皮修复模块
    def PhotoToImg(self):
        path = self.filename
        img = cv2.imread(path)
        work_img = cv2.bilateralFilter(img, 31, 100, 150)
        # 图像融合
        result_img = cv2.addWeighted(img, 0.3, work_img, 0.7, 0)
        cv2.imwrite("img_1.jpg", result_img)
        image = Image.open("img_1.jpg")
        # 锐度调节
        enh_img = ImageEnhance.Sharpness(image)
        image_sharped = enh_img.enhance(1.5)
        # 对比度调节
        con_img = ImageEnhance.Contrast(image_sharped)
        image_con = con_img.enhance(1.15)
        image_con.save(self.filename + '.jpg')
        return '照片修复完成'

    # 7、图片内容转word
    def PhotoToWord(self):
        table_engine = PPStructure(layout=False, recovery=True)
        img_path = self.filename
        save_folder = img_path + '\Desktop'
        img = cv2.imread(img_path)
        result = table_engine(img)
        h, w, _ = img.shape
        res = sorted_layout_boxes(result, w)
        convert_info_docx(img, res, save_folder, os.path.dirname(img_path + '\Desktop').split('.')[0])
        return '图片内容转word完成'

    # 8、PDF文字提取
    def PdfToRWord(self):
        ocr = PaddleOCR(use_angle_cls=True, lang="ch",
                        page_num=2)  # need to run only once to download and load model into memory
        img_path = self.filename
        result = ocr.ocr(img_path, cls=True)
        for idx in range(len(result)):
            res = result[idx]
            txts = [line[1][0] for line in res]
            log = open(self.filename + '.doc', mode="a", encoding="utf-8")
            for i in range(len(txts)):
                res = txts[i]
                for line in res:
                    print(line, file=log, end='')

        return 'PDF文字提取完成'

    # 9、图片压缩模块
    def ImageToLow(self):
        pic_path = self.filename
        out_path = self.filename + "-压缩后"
        target_size = 199
        quality = 90
        step = 5
        pic_type = '.jpg'
        # 读取图片bytes
        with open(pic_path, 'rb') as f:
            pic_byte = f.read()
        img_np = np.frombuffer(pic_byte, np.uint8)
        img_cv = cv2.imdecode(img_np, cv2.IMREAD_ANYCOLOR)
        current_size = len(pic_byte) / 1024
        print("图片压缩前的大小为(KB)：", current_size)
        a = current_size
        while current_size > target_size:
            pic_byte = cv2.imencode(pic_type, img_cv, [int(cv2.IMWRITE_JPEG_QUALITY), quality])[1]
            if quality - step < 0:
                break
            quality -= step
            current_size = len(pic_byte) / 1024
        print("图片压缩后的大小为(KB)：", current_size)
        b = current_size

        # 保存图片
        with open(out_path, 'wb') as f:
            f.write(BytesIO(pic_byte).getvalue())
        return "图片压缩完成", '\n', "压缩前的大小为(KB)：", a, '\n', "压缩后的大小为(KB)：", b

    # 10、PDF添加水印模块
    def PdfToMark(self):
        # 合并PDF水印
        watermark_pdf = PdfFileReader('水印.pdf')
        watermark_page = watermark_pdf.getPage(0)
        PdfFilie = self.filename
        pdf_reader = PdfFileReader(PdfFilie)
        pdf_writer = PdfFileWriter()
        for page in range(pdf_reader.getNumPages()):
            # 没有水印的页面
            original_page = pdf_reader.getPage(page)
            new_page = copy(watermark_page)
            # 加了水印的页面   下面的内容.mergePage(出现在上面的内容)
            new_page.mergePage(original_page)
            pdf_writer.addPage(new_page)
        with open(self.filename + '--加水印.pdf', 'wb') as f:
            pdf_writer.write(f)
            return "PDF添加水印完成"

    # 11、PDF转PPT模块
    def PdfToPpt(self):
        pdfFile = self.filename  # pdf路径
        pptFile = self.filename + ".PPT"  # ppt名称
        storePath = self.filename + "临时文件"  # 临时图片保存位置
        width = 7
        height = 7.5
        zoom = 2.0
        doc = fitz.open(pdfFile)
        picName = os.path.splitext(os.path.basename(pdfFile))[0]
        index = 0
        os.makedirs(storePath, exist_ok=True)
        images = []
        print(f"To convert: {pdfFile}")
        for pg in range(doc.page_count):
            page = doc[pg]
            index += 1
            rotate = int(0)
            print(f"\tconvert page {index}")
            # 每个尺寸的缩放系数(提高生成分辨率)
            zoom_x, zoom_y = zoom, zoom
            mat = fitz.Matrix(zoom_x, zoom_y)
            pm = page.get_pixmap(matrix=mat, alpha=False)
            imgName = '{}-{}.jpg'.format(picName, index)
            imgFile = os.path.join(storePath, imgName)
            pm.save(imgFile)

            images.append(imgFile)
        doc.close()
        ppt = pptx.Presentation()
        for i in images:
            layout = ppt.slide_layouts[0]  # 定义一个PPT页面样式
            slide = ppt.slides.add_slide(layout)

            slide.shapes.add_picture(
                image_file=i,
                left=Inches(1.5),
                top=Inches(0),
                width=Inches(width),
                height=Inches(height)
            )
        ppt.save(pptFile)
        shutil.rmtree(storePath)
        return "PDF转PPT完成"


# 定义打开的文件夹
class Changefile:
    def __init__(self, filepath):
        self.filepath = filepath

    #12、PDF合并
    def PdfToOne(self):
        file_merger = PdfFileMerger(strict=False)  # 初始化并设置非严格检查
        path = self.filepath + '\\'  # 合并后输出目录
        target_path = os.path.dirname(path)  # 合并pdf所在目录
        pdf_lst = [f for f in os.listdir(target_path) if f.endswith('.pdf')]  # 读取pdf
        pdf_lst = [os.path.join(target_path, filename) for filename in pdf_lst]  # 补全文件地址
        for pdf in pdf_lst:
            file_merger.append(PdfFileReader(pdf), 'tag')
        file_merger.addMetadata(
            {u'/Title': u'my title', u'/Creator': u'creator', '/Subject': 'subjects'})  # 补全pdf信息
        today = datetime.now()
        Time = today.strftime("%Y-%m-%d")
        file_merger.write(path + r"合并文件" + Time + r'.pdf')
        file_merger.close()
        file_merger.close()
        return 'PDF文件合并完成'

